﻿using ShkSimulation.carsharing.impl;
using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using ShkSimulation.carsharing;
using ShkSimulation.core.dao.input.loader;
using ShkSimulation.core.dao.output;
using ShkSimulation.core.template.model;
using ShkSimulation.desktop.component.parallel;
using ShkSimulation.desktop.component.tools;
using ShkSimulation.desktop.setting;
using ShkSimulation.desktop.setting.tools;
using ShkSimulation.desktop.util;
using Result = ShkSimulation.core.dao.output.result.Result;

namespace ShkSimulation.desktop {
    public partial class ShkSimulationForm : Form, ResetSimulation {
        
        public ShkSimulationForm() {
            InitializeComponent();
            Init();
        }

        private SimulationApplication application;

        private void RunSimulationButton_Click(object sender, EventArgs e) {
            if (application == null) {
                Console.WriteLine(@"请先加载");
                return;
            }
            开始仿真ToolStripMenuItem.Enabled = false;
            RunSimulationButton.Enabled = false;
            BottomStatusLabel.Text = @"运行中";
            CancelSimulationButton.Enabled = true;
            SimulationWorker.RunWorkerAsync();
        }
        
        private void SimulationWorker_DoWork(object sender, DoWorkEventArgs e) {
            Result result;
            if (ConfigManager.UserRunConfig.真实时间) {
                result = application.ConsinousRun(ConfigManager.UserRunConfig.仿真时长, ConfigManager.UserRunConfig.观察间隔);
            } else {
                result = application.StartRun(ConfigManager.UserRunConfig.仿真时长, ConfigManager.UserRunConfig.观察间隔);
            }
            ConsoleTextBox.Show(result);
            BottomStatusLabel.Text = @"运行结束：" + DateTime.Now.ToString(CultureInfo.InvariantCulture);
            Invoke(new Action(() => {
                RunSimulationButton.Enabled = true;
                开始仿真ToolStripMenuItem.Enabled = true;
                CancelSimulationButton.Enabled = false;
            }));
        }
        
        private void CancelButton_Click(object sender, EventArgs e) {
            application.SimulationNetwork.Cancel = true;
        }

        private void CheckAndResetSimulation(object sender, EventArgs e){
            if (CheckCancel()) {
                return;
            }
            Reset();
        }

        private bool CheckCancel() {
            if (!ConfigManager.UserSystemConfig.重置不再提醒) {
                MessageBoxDialogResult messageResult = MessageBoxForm.GetMessageResult(@"提示", @"要重置仿真吗？");
                ConfigManager.UserSystemConfig.重置不再提醒 = MessageBoxForm.Ignore(messageResult);
                if ((messageResult & MessageBoxDialogResult.Cancel) != 0) {
                    return true;
                }
            }
            return false;
        }

        private void CheckResetAndInitSimulation(object sender, EventArgs e) {
            if (CheckCancel()) {
                return;
            }
            Reset();
            CreateAndInitSimulation();
        }

        public void CreateAndInitSimulation(object sender = null, EventArgs e = null) {
            if (CreateSimulation()) {
                InitSimulation();
            }
        }

        public bool CreateSimulation() {
            Console.WriteLine($@"创建仿真：{DateTime.Now}");
            InputConfig config = ConfigManager.UserSimulationConfig.Convert();
            if (!CarsharingConfig.IsValidCarsharingConfig(config)) {
                Console.WriteLine($@"配置文件不能正常使用，请重新设置，ShkSimulationDesktop/data中有示例文件");
                MessageBox.Show(@"配置文件不能正常使用，请重新设置", @"提示");
                ConfigFormButton_Click(null, null);
                return false;
            }
            ResourceLoader loader = new ExcelResourceLoader();
            application = new SimulationApplication(config, loader, "Desktop");
            SimulationControl.SetSimulationApplication(application);
            StatisticConfigControl.SetSimulationApplication(application);
            OptimizationControl.SetSimulationApplication(application);
            ConsoleTextBox.SetSimulationApplication(application);
            RealMapControl.SetSimulationApplication(application);
            RealTimePerformanceStatisticsTool.SetSimulationApplication(application);
            return true;
        }

        public void InitSimulation(object sender = null, EventArgs e = null) {
            if (!application.Init(ConfigManager.UserRunConfig.仿真开始时刻)) {
                MessageBox.Show(@"初始化失败", @"提示");
                return;
            }
            RunSimulationButton.Enabled = true;
        }

        public void Reset() {
            Console.WriteLine($@"重置仿真：{DateTime.Now}");
            this.application = null;
            SimulationControl.Reset();
            StatisticConfigControl.Reset();
            OptimizationControl.Reset();
            ConsoleTextBox.Reset();
            RealMapControl.Reset();
        }

        private void ResultExportButton_Click(object sender, EventArgs e) {
            if (application?.ResultHolder == null) {
                MessageBox.Show(@"当前没有已加载仿真", @"提示");
                return;
            }
            string key = DateTime.Now.ToString("u");
            Result result = application.ResultHolder.GetCurrentResult(key);
            //DataTableResourceResult resourceResult = new DefaultDataTableResourceResult(result);
            //ResourceLoader loader = new ExcelResourceLoader();
            DialogResult dialogResult = SaveFileDialog.ShowDialog();
            if (dialogResult == DialogResult.OK) {
                string path = SaveFileDialog.FileName;
                ResultShower excelShower = new ExcelResultShower(path);
                excelShower.Show(result);
                //loader.SaveData(resourceResult, path);
                BottomStatusLabel.Text = $@"导出文件到：{path} {DateTime.Now.ToString(CultureInfo.InvariantCulture)}";
            }
        }

        private void ResetButton_Click(object sender, EventArgs e) {
            if (SimulationWorker.IsBusy) {
                application?.AddProcessInfo("仿真正在运行，请稍后");
                return;
            }
            RunSimulationButton.Enabled = false;
            CheckAndResetSimulation(null, null);
        }

        private void ClearConsoleButton_Click(object sender, EventArgs e) {
            ConsoleTextBox.Text = "";
        }

        private void ConfigFormButton_Click(object sender, EventArgs e) {
            ConfigForm setForm = new ConfigForm();
            setForm.ShowDialog();
        }

        private void EditFormButton_Click(object sender, EventArgs e) {
            NetworkEditForm form = new NetworkEditForm();
            DialogResult result = form.ShowDialog();
            if (result == DialogResult.Abort) {
                ConfigFormButton_Click(null, null);
            }else if (result != DialogResult.Cancel) {
                Console.WriteLine(@"由于输入文件更新了，仿真重置");
                Reset();
            }
        }

        public RealTimePerformanceStatisticsTool RealTimePerformanceStatisticsTool { get; set; } =
            new RealTimePerformanceStatisticsTool();

        private void PerformanceExportButton_Click(object sender, EventArgs e) {
            if (!RealTimePerformanceStatisticsTool.Enabaled) {
                MessageBox.Show("请先开启性能统计选项", "提示");
                return;
            }
            string saveFilePath = FileUtil.SaveFile(SaveFileDialog, $@"保存性能统计文件", $@"性能统计数据|*.xlsx", "performance.xlsx");
            if (saveFilePath == null) {
                return;
            }
            if (RealTimePerformanceStatisticsTool.Export(saveFilePath)) {
                Console.WriteLine($@"导出性能统计数据成功：{saveFilePath}");
            } else {
                Console.WriteLine($@"导出性能统计数据失败：{saveFilePath}");
            }
        }

        private void ParallelButton_Click(object sender, EventArgs e) {
            MultiSimulationForm form = new MultiSimulationForm();
            form.TopMost = true;
            form.Show();
        }

        private void 联系我ToolStripMenuItem_Click(object sender, EventArgs e) {
            OpenUrl("http://pklue.club/msgBoard");
        }

        private void 关于ShkSimulationToolStripMenuItem_Click(object sender, EventArgs e) {
            OpenUrl("https://gitee.com/pklue/shk-simulation");
        }
        
        private void OpenUrl(string url) {
            try {
                var processStartInfo = new ProcessStartInfo {
                    FileName = url,
                    UseShellExecute = true
                };
                Process.Start(processStartInfo);
            } catch (Exception exception) {
                MessageBox.Show("打开：失败,请重试或手动试试" + url);
            }
        }
    }
}